package com.liangplus.elasticsearch.service;

import com.liangplus.elasticsearch.entity.eo.ShrEO;
import com.liangplus.elasticsearch.entity.eo.UserPEO;
import com.liangplus.elasticsearch.utils.ESUtil;
import org.elasticsearch.action.admin.indices.analyze.AnalyzeAction;
import org.elasticsearch.action.admin.indices.analyze.AnalyzeRequestBuilder;
import org.elasticsearch.action.search.SearchAction;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

/**
 * Created by yumin on 2019/9/4.
 */
@Service
public class QueryService {

    @Autowired
    private  ElasticsearchTemplate elasticsearchTemplate;
    @Autowired
    private ESUtil esUtil;


    public  Page<ShrEO>   fullSearch(String keyword, int page, int size ){
        // 校验参数
        if (StringUtils.isEmpty(page))
            page = 0; // if page is null, page = 0

        if (StringUtils.isEmpty(size))
            size = 10; // if size is null, size default 10

        // 构造分页类
        Pageable pageable = PageRequest.of(page, size);

        MatchQueryBuilder shrNm= QueryBuilders.matchQuery("shrNm",keyword);
        WildcardQueryBuilder shrCd= QueryBuilders.wildcardQuery ("shrCd",keyword);
        WildcardQueryBuilder phoFull= QueryBuilders.wildcardQuery("phoFull",keyword);
        WildcardQueryBuilder phoSht= QueryBuilders.wildcardQuery("phoSht",keyword);
        // 构造查询 NativeSearchQueryBuilder
        NativeSearchQueryBuilder searchQueryBuilder = new NativeSearchQueryBuilder()
                .withPageable(pageable);
        if (!StringUtils.isEmpty(keyword)) {
            // keyword must not null
            searchQueryBuilder.withQuery(QueryBuilders.boolQuery().must(shrNm).mustNot(shrCd).mustNot(phoFull).mustNot(phoSht))
                    .withHighlightFields(withHighlight("shrNm","red"),withHighlight("shrCd","red"))
                    .withFields("shrNm","shrCd","phoFull","phoSht");
        }
        /*
        SearchQuery
        这个很关键，这是搜索条件的入口，
        elasticsearchTemplate 会 使用它 进行搜索
         */
        SearchQuery searchQuery = searchQueryBuilder.build();

        // page search
        Page<ShrEO> shrEOModelPage = elasticsearchTemplate.queryForPage(searchQuery, ShrEO.class);

        return shrEOModelPage;
    }

    public  Page<UserPEO>   fullSearchForUser(String keyword, int page, int size ){
        // 校验参数
        if (StringUtils.isEmpty(page))
            page = 0; // if page is null, page = 0

        if (StringUtils.isEmpty(size))
            size = 10; // if size is null, size default 10

        // 构造分页类
        Pageable pageable = PageRequest.of(page, size);

        // 构造查询 NativeSearchQueryBuilder
        NativeSearchQueryBuilder searchQueryBuilder = new NativeSearchQueryBuilder()
                .withPageable(pageable);
        if (!StringUtils.isEmpty(keyword)) {
            // keyword must not null
            searchQueryBuilder.withQuery(QueryBuilders.simpleQueryStringQuery(keyword));
        }
        /*
        SearchQuery
        这个很关键，这是搜索条件的入口，
        elasticsearchTemplate 会 使用它 进行搜索
         */
        SearchQuery searchQuery = searchQueryBuilder.build();

        // page search
        Page<UserPEO> shrEOModelPage = elasticsearchTemplate.queryForPage(searchQuery, UserPEO.class);

        return shrEOModelPage;
    }

    public HighlightBuilder.Field withHighlight(String filed, String color){
        return  new HighlightBuilder.Field(filed).preTags("<em style='color:'"+color+"'>").postTags("</em>");
    }

    public Page<UserPEO>    termSearch(String keyword, int page, int size ){
        // 校验参数
        if (StringUtils.isEmpty(page))
            page = 0; // if page is null, page = 0

        if (StringUtils.isEmpty(size))
            size = 10; // if size is null, size default 10

        // 构造分页类
        Pageable pageable = PageRequest.of(page, size);

        // 构造查询 NativeSearchQueryBuilder
        NativeSearchQueryBuilder searchQueryBuilder = new NativeSearchQueryBuilder()
                .withPageable(pageable);
        if (!StringUtils.isEmpty(keyword)) {
            // keyword must not null
            searchQueryBuilder.withQuery(QueryBuilders.termsQuery("pic",keyword)).withHighlightFields(new HighlightBuilder.Field("simplePNm"));
        }
        /*
            SearchQuery
            这个很关键，这是搜索条件的入口，
            elasticsearchTemplate 会 使用它 进行搜索
         */
        SearchQuery searchQuery = searchQueryBuilder.build();
        // page search
        Page<UserPEO> userPEOModelPage = elasticsearchTemplate.queryForPage(searchQuery, UserPEO.class);

        return userPEOModelPage;
    }


    public Page<UserPEO>   termQuery(String keyword, int page, int size ){
        // 校验参数
        if (StringUtils.isEmpty(page))
            page = 0; // if page is null, page = 0

        if (StringUtils.isEmpty(size))
            size = 10; // if size is null, size default 10

        // 构造分页类
        Pageable pageable = PageRequest.of(page, size);

        // 构造查询 NativeSearchQueryBuilder
        NativeSearchQueryBuilder searchQueryBuilder = new NativeSearchQueryBuilder()
                .withPageable(pageable);
        if (!StringUtils.isEmpty(keyword)) {
            // keyword must not null
            searchQueryBuilder.withQuery(QueryBuilders.multiMatchQuery(keyword,"simplePNm","pic","orgPic"))
                    .withHighlightFields(new HighlightBuilder.Field("simplePNm"));
        }
        /*
            SearchQuery
            这个很关键，这是搜索条件的入口，
            elasticsearchTemplate 会 使用它 进行搜索
         */
        SearchQuery searchQuery = searchQueryBuilder.build();
        // page search
        Page<UserPEO> userPEOModelPage = elasticsearchTemplate.queryForPage(searchQuery, UserPEO.class);


        return userPEOModelPage;
    }


    public SearchHits multiMatchQuery(String keyword, int page, int size ){

        // 构造分页类
        SearchResponse response = elasticsearchTemplate.getClient().prepareSearch("liangplus_user","liangplus_stockcode")
                .setQuery( QueryBuilders.multiMatchQuery(keyword,"simplePNm","userId","pic","orgPic","shrCd","shrNm","shr","phoFull","phoSht"))
                .highlighter(new HighlightBuilder().field("simplePNm").preTags("<em style='color:'red'>").postTags("</em>")) // 添加高亮的字段
                .setFrom(page)
                .setSize(size)
                .setExplain(true)
                .execute().actionGet();
        return response.getHits();
    }

    public SearchHits multiMatchQuery2(String keyword, int page, int size){
        MatchQueryBuilder simplePNm= QueryBuilders.matchQuery("simplePNm",keyword);
        MatchQueryBuilder pic= QueryBuilders.matchQuery("pic",keyword);
        MatchQueryBuilder orgPic= QueryBuilders.matchQuery("orgPic",keyword);
        //这里设置三个字段搜索的关系
        QueryBuilder queryBuilder = QueryBuilders.boolQuery()
                .should(simplePNm)
                .should(orgPic)
                .should(pic);

        // 构造分页类
        SearchResponse response = elasticsearchTemplate.getClient().prepareSearch("liangplus_user")
                .setQuery(queryBuilder)
                .highlighter(new HighlightBuilder().field("simplePNm").preTags("<em style='color:'red'>").postTags("</em>")) // 添加高亮的字段
                .setFrom(page)
                .setSize(size)
                .setExplain(true)
                .execute().actionGet();
        SearchHits responseHits = response.getHits();
        return response.getHits();
    }



}
